package platform

import (
	"os"
	"syscall"
	"unsafe"
)

type shellExecuteInfo struct {
	cbSize       uint32
	fMask        uint32
	hwnd         syscall.Handle
	lpVerb       *uint16
	lpFile       *uint16
	lpParameters *uint16
	lpDirectory  *uint16
	nShow        int32
	hInstApp     syscall.Handle
	lpIDList     uintptr
	lpClass      *uint16
	hKeyClass    syscall.Handle
	dwHotKey     uint32
	hIcon        syscall.Handle
	hProcess     syscall.Handle
}

const (
	sEE_MASK_NOCLOSEPROCESS = 0x00000040
	sW_HIDE                 = 0
)

// IsAdmin 检查当前进程是否具有管理员权限
func IsAdmin() bool {
	_, err := os.Open("\\\\.\\PHYSICALDRIVE0")
	return err == nil
}

// hideConsoleWindow 隐藏控制台窗口
func hideConsoleWindow() {
	hwnd, _, _ := procGetConsoleWindow.Call()
	if hwnd != 0 {
		procShowWindow.Call(hwnd, uintptr(sW_HIDE))
	}
}

// RunAsAdmin 确保程序以管理员权限运行
func RunAsAdmin() error {
	if IsAdmin() {
		hideConsoleWindow()
		return nil
	}

	exe, err := os.Executable()
	if err != nil {
		return err
	}

	verb := "runas"
	verbPtr, _ := syscall.UTF16PtrFromString(verb)
	exePtr, _ := syscall.UTF16PtrFromString(exe)
	cwdPtr, _ := syscall.UTF16PtrFromString("")

	info := shellExecuteInfo{
		cbSize:      uint32(unsafe.Sizeof(shellExecuteInfo{})),
		fMask:       sEE_MASK_NOCLOSEPROCESS,
		lpVerb:      verbPtr,
		lpFile:      exePtr,
		nShow:       sW_HIDE,
		hwnd:        0,
		lpDirectory: cwdPtr,
	}

	ret, _, err := procShellExecuteExW.Call(uintptr(unsafe.Pointer(&info)))
	if ret == 0 {
		return err
	}

	os.Exit(0)
	return nil
}
